/* This code licensed under GNU GPLv3.
 * You can get a copy of the license text along with the program.
 * Or you can get a copy at https://www.gnu.org/licenses/gpl-3.0.en.html
 * E-Mail of the author: dreemurrcode@ya.ru
 * Program repository: https://notabug.org/reicode/CrossesCircles
 */

#include <ncurses.h>
#include <stdlib.h>

void printgf(int (*gf)[3][3]) {
    for (int i = 0; i < 3; i++) {
        printw("| ");
        for (int j = 0; j < 3; j++) {
            if ((*gf)[i][j] == 1) printw("X | ");
            else if ((*gf)[i][j] == 2) printw("O | ");
            else printw("  | ");
        }
        printw("\n");
    }
    refresh();
}

void creategf(int (*gf)[3][3]) {
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            (*gf)[i][j] = 0;
}

void changegf_x(int (*gf)[3][3]) {
    while(1) {
        int x, y;
        printw("X: ");
        refresh();
        scanw("%d %d", &x, &y);
        if ((*gf)[x-1][y-1] != 0) continue;
        else {
            (*gf)[x-1][y-1] = 1;
            break;
        }
    }
}

void changegf_o(int (*gf)[3][3]) {
    while(1) {
        int x, y;
        printw("O: ");
        refresh();
        scanw("%d %d", &x, &y);
        if ((*gf)[x-1][y-1] != 0) continue;
        else {
            (*gf)[x-1][y-1] = 2;
            break;
        }
    }
}

int checkgf(int (*gf)[3][3]) {
    for (int i = 0; i < 3; i++) if ((*gf)[i][0] == 1 && (*gf)[i][1] == 1 && (*gf)[i][2] == 1) return 1;
    for (int i = 0; i < 3; i++) if ((*gf)[0][i] == 1 && (*gf)[1][i] == 1 && (*gf)[2][i] == 1) return 1;
    if ((*gf)[0][0] == 1 && (*gf)[1][1] == 1 && (*gf)[2][2] == 1) return 1;
    if ((*gf)[0][2] == 1 && (*gf)[1][1] == 1 && (*gf)[2][0] == 1) return 1;

    for (int i = 0; i < 3; i++) if ((*gf)[i][0] == 2 && (*gf)[i][1] == 2 && (*gf)[i][2] == 2) return 2;
    for (int i = 0; i < 3; i++) if ((*gf)[0][i] == 2 && (*gf)[1][i] == 2 && (*gf)[2][i] == 2) return 2;
    if ((*gf)[0][0] == 2 && (*gf)[1][1] == 2 && (*gf)[2][2] == 2) return 2;

    if ((*gf)[0][2] == 2 && (*gf)[1][1] == 2 && (*gf)[2][0] == 2) return 2;

    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            if ((*gf)[i][j] == 0) {
                return 0;
            }

    return 3;
}

int main() {
    initscr();
    int gameField[3][3];
    creategf(&gameField);
    while(1) {
        if (checkgf(&gameField) == 2) {
            printw("Circles won!\n");
            printgf(&gameField);
            break;
        }
        printgf(&gameField);
        changegf_x(&gameField);
        clear();
        refresh();
        printgf(&gameField);
	if (checkgf(&gameField) == 1) {
            printw("Crosses  won!\n");
            // printgf(&gameField);
            break;
        }
        if (checkgf(&gameField) == 3) {
            printw("Draft!\n");
            printgf(&gameField);
            break;
        }
        changegf_o(&gameField);
        clear();
        refresh();
    }
    getch();
    endwin();
    return 0;
}
